package com.zhsource.article.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.zhsource.article.domain.Article;
import com.zhsource.article.mapper.ArticleMapper;
import com.zhsource.article.query.ArticleQuery;
import com.zhsource.article.service.IArticleService;
import com.zhsource.constants.ArticleConstant;
import com.zhsource.exception.GlobalException;
import com.zhsource.system.domain.Employee;
import com.zhsource.tourist.dto.ArticleCountDto;
import com.zhsource.tourist.dto.ArticleDto;
import com.zhsource.tourist.vo.ArchivesVo;
import com.zhsource.tourist.vo.ArticleVo;
import com.zhsource.utils.LoginContext;
import io.minio.MinioClient;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * <p>@ClassName：ArticleServiceImpl
 * <p>@Date 2023/10/17  13:01
 *
 * @Author zzl
 **/
@Slf4j
@Service

public class ArticleServiceImpl implements IArticleService {

//    private static final ConcurrentHashMap<String, List<Article>> articleTreeMap = new ConcurrentHashMap<>();
    private static final String ACCESSKEY = "minioadmin";
    private static final String SECREKEY = "minioadmin123?";
    private static final String ADDRESS = "http://115.159.88.63:9090";
    private static final String BUCKETNAME = "java-very-good-0712";

    @Autowired
    private ArticleMapper articleMapper;

    @Autowired
    private LoginContext loginContext;

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private RedisTemplate  redisTemplate;


    @Override
    public List<Article> list() {
        return articleMapper.list();
    }

    @Override
    public Article selectById(Long id) {
        return articleMapper.selectById(id);
    }

    @Override
    public PageInfo<Article> page(ArticleQuery articleQuery) {
        // 1.下面这句代码表示开启分页，会将紧挨着这句代码的下一次数据库执行进行分页，切记一定要放在要分页的SQL语句前面执行
        PageHelper.startPage(articleQuery.getCurrentPage(), articleQuery.getPageSize());

        // 2.执行SQL语句带条件查询，SQL语句不需要进行分页
        List<Article> page = articleMapper.page(articleQuery);
        // 3.将查询结果转换为PageInfo对象，PageInfo对象中有前端分页所需要的各种参数
        PageInfo<Article> pageInfo = new PageInfo<>(page);
        // 4.响应总条数和分页信息
        return pageInfo;

    }


    @Override
    @CacheEvict(cacheNames = ArticleConstant.ARTICLE_TYPE_NAMES, key = ArticleConstant.ARTICLE_TYPE_CACHE_TREE)
    public void update(Article article) {
        articleMapper.update(article);

        Article articleMongo = mongoTemplate.findOne(new Query(Criteria.where("id").is(article.getId())), Article.class);
        article.set_id(articleMongo.get_id());
        mongoTemplate.save(article);

    }

    @Override
    @CacheEvict(cacheNames = ArticleConstant.ARTICLE_TYPE_NAMES, key = ArticleConstant.ARTICLE_TYPE_CACHE_TREE)
    public void insert(Article article) {
        Employee employee = loginContext.getEmployee();
        // 操作数据库
        article.setUserId(employee.getId());
        articleMapper.insert(article);

        // 存储到mongodb中
        mongoTemplate.save(article);
    }

    @Override
    @CacheEvict(cacheNames = ArticleConstant.ARTICLE_TYPE_NAMES, key = ArticleConstant.ARTICLE_TYPE_CACHE_TREE)
    public void delete(Long id) {
        try {
            Article article = articleMapper.selectById(id);
            String articlePic = article.getArticlePic();
            // 构建一个Minio客户端
            MinioClient minioClient = MinioClient.builder()
                    //创建容器时指定的账号
                    .credentials(ArticleServiceImpl.ACCESSKEY, ArticleServiceImpl.SECREKEY)
                    //上传地址
                    .endpoint(ArticleServiceImpl.ADDRESS).build();
            String[] split = articlePic.split("/");

            minioClient.removeObject(ArticleServiceImpl.BUCKETNAME, split[split.length - 1]);
            articleMapper.delete(id);

            mongoTemplate.remove(new Query(Criteria.where("id").is(article.getId())),Article.class);

        } catch (Exception e) {
            throw new GlobalException("文章删除异常，请重试");
        }
    }

    @Override
    public void batchDel(List<Long> ids) {
        articleMapper.batchDel(ids);
    }

    @Override
    public List<ArchivesVo> getArchivesTime() {
        return articleMapper.getArchivesTime();
    }

    @Override
    public List<Article> getArticleByTag(Long articleId) {
        return articleMapper.getArticleByTag(articleId);
    }

    @Override
    public List<Article> getArticleByArticleTypeId(Long articleTypeId) {
        return articleMapper.getArticleByArticleTypeId(articleTypeId);
    }

    @Override
    public List<ArticleVo> getArchivesList(String time) {

        time = "all".equalsIgnoreCase(time) ? "" : time;
        List<Article> list = articleMapper.getArchivesList(time);

        //根据年份进行分组：百度看例子
        //String保存的是年份，List<BlogArticle>保存当前年份的集合
        Map<String, List<Article>> resultMap = list.stream().collect(Collectors.groupingBy(Article::getYear));

        List<ArticleVo> result = new ArrayList<>();
        //遍历resultMap，封装结果进行返回
        for(String year : resultMap.keySet()){
            ArticleVo vo = new ArticleVo();
            vo.setYear(year);
            vo.setArticleList(resultMap.get(year));
            result.add(vo);
        }
        return result;
    }

    @Override
    public List<ArticleDto> getArticleList(String time) {
        time = "all".equalsIgnoreCase(time) ? "" : time;
        List<Article> list = articleMapper.getArticleList(time);

        //根据年份进行分组：百度看例子
        //String保存的是年份，List<BlogArticle>保存当前年份的集合
        Map<String, List<Article>> resultMap = list.stream().collect(Collectors.groupingBy(Article::getYear));

        List<ArticleDto> result = new ArrayList<>();
        //遍历resultMap，封装结果进行返回
        for (String year : resultMap.keySet()) {
            ArticleDto dto = new ArticleDto();
            dto.setYear(year);
            dto.setArticleList(resultMap.get(year));
            result.add(dto);
        }
        return result;

    }

    @Override
    public void incrementLikeCount(Long articleId) {
//        String key = "article_like_count:" + articleId;
//        // 在这里你可以根据具体的业务逻辑来实现点赞数的更新
//        // 例如，你可以通过 Redis 来实现点赞数的存储和更新
//        // 你可以使用 Redis 的数据结构来存储点赞数，比如 String 或 Hash 等
//        // 在这里假设你使用 Redis 中的 String 来存储点赞数
//        redisTemplate.opsForValue().increment(key, 1);
        // 在这里你可以根据具体的业务逻辑来实现点赞数的更新
        // 假设你的文章点赞数存储在数据库中，你可以调用相应的方法来增加点赞数
        Article article = articleMapper.selectById(articleId);
        if (article != null) {
            int likeCount = article.getArticleStarNum();
            likeCount++;
            article.setArticleStarNum(likeCount);
            articleMapper.update(article);
        } else {
            throw new GlobalException("文章不存在");
        }
    }

    @Override
    public List<Article> getEchartsData() {
        return articleMapper.getEchartsData();
    }

    @Override
    public List<ArticleCountDto> getPieChartData() {
        return articleMapper.getPieChartData();
    }


}
